#pragma once
#include <functional>
#include <string>
#include <signal.h>
#include "Log.hpp"
#include "Socket.hpp"

using func_t = std::function<std::string(std::string &package)>;
class TcpServe
{
public:
    TcpServe(uint16_t port,func_t callback):port_(port),callback_(callback)
    {
    }
    void Init()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        lg(Info, "init server .... done");
    }
    void Start()
    {
        signal(SIGCHLD, SIG_IGN);
    // 忽略管道破裂信号（避免客户端断开后服务端崩溃）
    signal(SIGPIPE, SIG_IGN);
        while(true)
        {
            string clientip;
            uint16_t port;
            int sockfd=listensock_.Accept(clientip, port);
            if(sockfd<0) continue;
            lg(Info, "accept a new link, sockfd: %d, clientip: %s, clientport: %d", sockfd, clientip.c_str(), port);
            if(fork()==0)
            {
                listensock_.Close();//关闭子进程监听
                //执行任务
                string cmz;
                while(true)
                {
                    char buffer[128];
                    ssize_t n=read(sockfd,buffer,sizeof(buffer));
                    if(n>0)
                    {
                        buffer[n]=0;
                        cmz+=buffer;
                        lg(Debug, "debug:\n%s", cmz.c_str());
                        while(true)//多个请求时，一直处理，写入
                        {
                        string info=callback_(cmz);
                        if (info.empty()) break;
                        write(sockfd,info.c_str(),info.size());
                        }
                    }
                    else if(n==0) break;
                    else break;
                }
                exit(0);
            }
            close(sockfd);
        }
    }
    ~TcpServe()
    {

    }
private:
    uint16_t port_;
    Sock listensock_;
    func_t callback_;
};